package com.wuuxiang.i5xforyou.service.impl;

import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.TimeUnit;

import org.apache.commons.lang.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Service;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.wuuxiang.i5xforyou.common.consts.Consts;
import com.wuuxiang.i5xforyou.common.domain.ResultMsg;
import com.wuuxiang.i5xforyou.common.domain.Results;
import com.wuuxiang.i5xforyou.common.redis.RedisKey;
import com.wuuxiang.i5xforyou.common.service.impl.BaseServiceImpl;
import com.wuuxiang.i5xforyou.service.CommonService;
import com.wuuxiang.i5xforyou.service.ValidateSMSService;
import com.wuuxiang.i5xforyou.utils.HttpUtil;
import com.wuuxiang.i5xforyou.vo.PhoSmsVerifyCodeVo;
import com.wuuxiang.jdbc.spring.boot.autoconfigure.dao.O2OJdbcRepository;
import com.wuuxiang.utils.validator.ValidatorUtil;

@Service("validateSMSService")
public class ValidateSMSServiceImpl extends BaseServiceImpl implements ValidateSMSService{

	@Autowired
	private StringRedisTemplate stringRedisTemplate;
	
	@Autowired
	private CommonService commonService;
	
	@Autowired
	private O2OJdbcRepository<PhoSmsVerifyCodeVo> o2oPsvDao;
	
    public ResultMsg getVerifyCode(String phoneNo, String leftTime, String mpId) {
        // status 0 正常  1异常错误  2短信通道异常  3需要重新进入的错误。
    	ResultMsg resultMsg = new ResultMsg();
    	String gcId = commonService.getGcIdByMpId(mpId);
    	if(gcId==null) {
    		log.error("获取短信验证码失败(getVerifyCode):云端微信业务未绑定门店");
        	resultMsg.setState(Results.ERROR);
        	resultMsg.setFlag(1);
        	resultMsg.setMsgEntity(0);
        	resultMsg.setException(new Exception("获取短信验证码失败(getVerifyCode):云端微信业务未绑定门店"));
            return resultMsg;
    	}
        //1.短信倒计时限制
        String smsCode = stringRedisTemplate.opsForValue().get(RedisKey.REDIS_SMSSENDTIME + "_" + gcId + "_" + phoneNo);
        int leftSec = Integer.parseInt(StringUtils.isBlank(leftTime)?"60":leftTime);
        leftSec = leftSec<60?60:leftSec;
        if (StringUtils.isNotBlank(smsCode)) {
            long sec = leftSec - ((System.currentTimeMillis() - Long.parseLong(smsCode.toString())) / 1000); // 间隔秒;
            if (sec > 0) {
            	resultMsg.setState(Results.SUCCESS);
            	resultMsg.setFlag(0);
            	resultMsg.setMsgEntity(sec);
            	resultMsg.setMsg("短信验证码已发送," + sec + "秒后请重试");
                return resultMsg;
            }
        }

        JSONObject postData = new JSONObject();
        postData.put("phoneNo", phoneNo);
        postData.put("codefrom", 2);
        postData.put("codeon", 3);
        postData.put("gcID", gcId);
        Map<String, String> params = new HashMap<String, String>();
		params.put("data", postData.toString());
        //2.调用云端发送验证码接口 codefrom 2微信 codeon 3快速启用
        String url_GetSmsVerifyCode = Consts.CLOUD_API_URL + "tcsl/GetSmsVerifyCode.htm";
        //{"errorCode":"200","errorText":"成功","returnCode":1}
        try {
            JSONObject json_GetSmsVerifyCode = HttpUtil.doPostJSONObject(url_GetSmsVerifyCode, params);
            int return_code = json_GetSmsVerifyCode.getIntValue("returnCode");
            String error_code = json_GetSmsVerifyCode.getString("errorCode");
            String error_Text = json_GetSmsVerifyCode.getString("errorText");
            if (return_code == 1 && "200".equals(error_code)){
            	stringRedisTemplate.opsForValue().set(RedisKey.REDIS_SMSSENDTIME + "_" + gcId + "_" + phoneNo,String.valueOf(System.currentTimeMillis()), Long.valueOf(leftSec), TimeUnit.SECONDS);
                resultMsg.setState(Results.SUCCESS);
            	resultMsg.setFlag(0);
            	resultMsg.setMsgEntity(leftSec);
            	resultMsg.setMsg("短信验证码已发送,请您稍后填写");
                return resultMsg;
            }
			// 记录Cat.logEvent
			//Cat.logEvent("O2O_API_URL.GetSmsVerifyCode", error_code, "Failure", "URL:["+url_GetSmsVerifyCode+"]");

            log.error("获取短信验证码失败(getVerifyCode):" + error_Text + ",url:" + url_GetSmsVerifyCode + ",params:" + JSON.toJSONString(params) + ",return:" + json_GetSmsVerifyCode);
            resultMsg.setState(Results.ERROR);
            resultMsg.setFlag(1);
            resultMsg.setMsgEntity(0);
            resultMsg.setException(new Exception("获取短信验证码失败:" + error_Text));
            return resultMsg;
        } catch (Exception e) {
			// 记录Cat.logError
			//StringBuilder message = new StringBuilder("获取短信验证码失败{url_GetSmsVerifyCode:").append(url_GetSmsVerifyCode).append("}");
	    	//Cat.logError(message.toString(), e);

        	log.error("获取短信验证码失败(getVerifyCode):" + e.toString() + ",url:" + url_GetSmsVerifyCode + ",params:" + JSON.toJSONString(params));
        	resultMsg.setState(Results.ERROR);
        	resultMsg.setFlag(1);
        	resultMsg.setMsgEntity(0);
        	resultMsg.setException(new Exception("获取短信验证码失败:" + e.getMessage()));
            return resultMsg;
        }
    }
    
    @Override
    public ResultMsg checkPhoneSmsVerifyCode(String phoneNo, String verifyCode) {

        ResultMsg resultMsg = new ResultMsg();

        // 1.判断手机号是否正确
		if (StringUtils.isBlank(phoneNo) || !ValidatorUtil.isMobile(phoneNo.trim())) {
			resultMsg.setState(Results.ERROR);
            resultMsg.setException(new Exception("请输入正确手机号！"));
            return resultMsg;
        }

        // 2.获取半小时内的短息发送记录
        String sql = "select ps.verifycode, ps.createdate from PHO_SMSVERIFYCODE ps where ps.codefrom = 2 and ps.codeon = 3 AND SYSDATE - ps.createdate <= 1/48 AND ps.phoneno= ? order by ps.createdate desc";
        List<PhoSmsVerifyCodeVo> psvlist = o2oPsvDao.getList(sql, PhoSmsVerifyCodeVo.class, phoneNo);
		if (psvlist == null || psvlist.isEmpty()) {
			resultMsg.setState(Results.ERROR);
            resultMsg.setException(new Exception("请先获取短信验证码"));
            return resultMsg;
        }
		// 4.排序验证码顺序及装载短信验证码记录
		Map<Integer, String> verifyCodeMap = new HashMap<Integer, String>(psvlist.size());
		for (int i = 0; i < psvlist.size(); i++) {
			verifyCodeMap.put(i, psvlist.get(i).getVerifycode());
		}
		// 5.未检索到短信验证码说明填写错误，获取到但不是最新的已过期
		if (!verifyCodeMap.containsValue(verifyCode)){
			resultMsg.setState(Results.ERROR);
			resultMsg.setException(new Exception("短信验证码错误,请重试"));
            return resultMsg;
		} else if (!verifyCode.equals(verifyCodeMap.get(0))){
			resultMsg.setState(Results.ERROR);
			resultMsg.setException(new Exception("短信验证码已过期,请重新获取"));
	        return resultMsg;
		}

        resultMsg.setState(Results.SUCCESS);
        resultMsg.setFlag(1);
        return resultMsg;
    }
    
}
